home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
emulator
/
bsvc-1.000
/
bsvc-1
/
bsvc-1.0.4
/
src
/
Assemblers
/
68kasm
/
assemble.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-26
|
7KB
|
237 lines
/******************************************************************************
* $Id: assemble.c,v 1.1 1994/08/29 23:53:27 bmott Exp $
******************************************************************************
*
* ASSEMBLE.C
* Assembly Routines for 68000 Assembler
*
* Function: processFile()
* Assembles the input file. For each pass, the function
* passes each line of the input file to assemble() to be
* assembled. The routine also makes sure that errors are
* printed on the screen and listed in the listing file
* and keeps track of the error counts and the line
* number.
*
* assemble()
* Assembles one line of assembly code. The line argument
* points to the line to be assembled, and the errorPtr
* argument is used to return an error code via the
* standard mechanism. The routine first determines if the
* line contains a label and saves the label for later
* use. It then calls instLookup() to look up the
* instruction (or directive) in the instruction table. If
* this search is successful and the parseFlag for that
* instruction is TRUE, it defines the label and parses
* the source and destination operands of the instruction
* (if appropriate) and searches the flavor list for the
* instruction, calling the proper routine if a match is
* found. If parseFlag is FALSE, it passes pointers to the
* label and operands to the specified routine for
* processing.
*
* Usage: processFile()
*
* assemble(line, errorPtr)
* char *line;
* int *errorPtr;
*
* Author: Paul McKee
* ECE492 North Carolina State University
*
* Date: 12/13/86
*
* Copyright 1990-1991 North Carolina State University. All Rights Reserved.
*
******************************************************************************
* $Log: assemble.c,v $
* Revision 1.1 1994/08/29 23:53:27 bmott
* Initial revision
*
*****************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include "asm.h"
extern int loc; /* The assembler's location counter */
extern char pass2; /* Flag set during second pass */
extern char endFlag; /* Flag set when the END directive is encountered */
extern char continuation; /* TRUE if the listing line is a continuation */
extern int lineNum;
extern int errorCount, warningCount;
extern char line[256]; /* Source line */
extern FILE *inFile; /* Input file */
extern FILE *listFile; /* Listing file */
extern char listFlag;
processFile()
{
char capLine[256];
int error;
char pass;
pass2 = FALSE;
for (pass = 0; pass < 2; pass++) {
loc = 0;
lineNum = 1;
endFlag = FALSE;
errorCount = warningCount = 0;
while(!endFlag && fgets(line, 256, inFile)) {
strcap(capLine, line);
error = OK;
continuation = FALSE;
if (pass2 && listFlag)
listLoc();
assemble(capLine, &error);
if (pass2) {
if (error > MINOR)
errorCount++;
else if (error > WARNING)
warningCount++;
if (listFlag) {
listLine(line, lineNum);
printError(listFile, error, -1);
}
printError(stderr, error, lineNum);
}
lineNum++;
}
if (!pass2) {
pass2 = TRUE;
/* puts("************************************************************");
puts("******************** STARTING PASS 2 *********************");
puts("************************************************************"); */
}
rewind(inFile);
}
}
assemble(line, errorPtr)
char *line;
int *errorPtr;
{
symbolDef *define();
instruction *tablePtr;
flavor *flavorPtr;
opDescriptor source, dest;
char *p, *start, label[SIGCHARS+1], size, f, sourceParsed, destParsed;
char *skipSpace(), *instLookup(), *opParse();
unsigned short mask, i;
p = start = skipSpace(line);
if (*p && *p != '*') {
i = 0;
do {
if (i < SIGCHARS)
label[i++] = *p;
p++;
} while (isalnum(*p) || *p == '.' || *p == '_' || *p == '$');
label[i] = '\0';
if ((isspace(*p) && start == line) || *p == ':') {
if (*p == ':')
p++;
p = skipSpace(p);
if (*p == '*' || !*p) {
define(label, loc, pass2, errorPtr);
return;
}
}
else {
p = start;
label[0] = '\0';
}
p = instLookup(p, &tablePtr, &size, errorPtr);
if (*errorPtr > SEVERE)
return;
p = skipSpace(p);
if (tablePtr->parseFlag) {
/* Move location counter to a word boundary and fix
the listing before assembling an instruction */
if (loc & 1) {
loc++;
listLoc();
}
if (*label)
define(label, loc, pass2, errorPtr);
if (*errorPtr > SEVERE)
return;
sourceParsed = destParsed = FALSE;
flavorPtr = tablePtr->flavorPtr;
for (f = 0; (f < tablePtr->flavorCount); f++, flavorPtr++) {
if (!sourceParsed && flavorPtr->source) {
p = opParse(p, &source, errorPtr);
if (*errorPtr > SEVERE)
return;
/* printOp(&source, "source"); */
sourceParsed = TRUE;
}
if (!destParsed && flavorPtr->dest) {
if (*p != ',') {
NEWERROR(*errorPtr, SYNTAX);
return;
}
p = opParse(p+1, &dest, errorPtr);
if (*errorPtr > SEVERE)
return;
if (!isspace(*p) && *p) {
NEWERROR(*errorPtr, SYNTAX);
return;
}
/* printOp(&dest, "destination"); */
destParsed = TRUE;
}
if (!flavorPtr->source) {
/* puts("Zero-operand instruction found"); */
mask = pickMask(size, flavorPtr, errorPtr);
(*flavorPtr->exec)(mask, errorPtr);
return;
}
else if ((source.mode & flavorPtr->source) && !flavorPtr->dest) {
/* puts("One operand instruction found"); */
if (!isspace(*p) && *p) {
NEWERROR(*errorPtr, SYNTAX);
return;
}
mask = pickMask(size, flavorPtr, errorPtr);
(*flavorPtr->exec)(mask, size, &source, &dest, errorPtr);
return;
}
else if (source.mode & flavorPtr->source
&& dest.mode & flavorPtr->dest) {
/* puts("Two operand instruction found"); */
mask = pickMask(size, flavorPtr, errorPtr);
(*flavorPtr->exec)(mask, size, &source, &dest, errorPtr);
return;
}
}
NEWERROR(*errorPtr, INV_ADDR_MODE);
}
else {
(*tablePtr->exec)(size, label, p, errorPtr);
return;
}
}
}
int pickMask(size, flavorPtr, errorPtr)
int size;
flavor *flavorPtr;
int *errorPtr;
{
if (!size || size & flavorPtr->sizes)
if (size & (BYTE | SHORT))
return flavorPtr->bytemask;
else if (!size || size == WORD)
return flavorPtr->wordmask;
else
return flavorPtr->longmask;
NEWERROR(*errorPtr, INV_SIZE_CODE);
return flavorPtr->wordmask;
}